﻿namespace AgileDashboard.AppCode
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    using Microsoft.Security.Application;

    /// <summary>
    /// DAO for fetching Story objects
    /// </summary>
    public class StoryDao : DaoBase
    {
        public StoryDao(IDataConnection dataConnection) : base(dataConnection)
        {
        }


        /// <summary>
        /// Returns active user stories for a given project name
        /// </summary>
        /// <param name="projectName">A valid project name</param>
        /// <returns>An ICollection of Story objects</returns>
        public ICollection<Story> GetAllActiveStoriesInProject(string projectName)
        {
            if (projectName == null)
            {
                throw new ArgumentNullException("projectName");
            }

            var dao = new ProjectDao(DataConnection);
            var project = dao.GetProjectByName(projectName);

            if (project == null)
            {
                throw new ApplicationException("project is null");
            }

            return GetAllStoriesInProjectByStatus(project, null);
        }

        /// <summary>
        /// Returns active user stories for a given project object
        /// </summary>
        /// <param name="project">A valid project object</param>
        /// <returns>An ICollection of Story objects</returns>
        public ICollection<Story> GetAllActiveStoriesInProject(Project project)
        {
            if (project == null)
            {
                throw new ArgumentNullException("project");
            }
            return this.GetAllStoriesInProjectByStatus(project, null);
        }


        /// <summary>
        /// Returns active user stories for a given project name
        /// </summary>
        /// <param name="projectName">A valid project name</param>
        /// <param name="status">a valid story status value to filter on</param>
        /// <returns>An ICollection of Story objects</returns>
        public ICollection<Story> GetAllStoriesInProjectByStatus(string projectName, string status)
        {
            if (projectName == null)
            {
                throw new ArgumentNullException("projectName");
            }
            if (status == null)
            {
                throw new ArgumentNullException("status");
            }

            var dao = new ProjectDao(DataConnection);
            var project = dao.GetProjectByName(projectName);

            if (project == null)
            {
                throw new ApplicationException("project is null");
            }

            return this.GetAllStoriesInProjectByStatus(project, status);
        }

        /// <summary>
        /// Returns active user stories for a given project with a particular status
        /// </summary>
        /// <param name="project">A valid Project object</param>
        /// <param name="status">a valid story status value to filter on</param>
        /// <returns>An ICollection of Story objects</returns>
        public ICollection<Story> GetAllStoriesInProjectByStatus(Project project, string status)
        {
            if (project == null)
            {
                throw new ArgumentNullException("project");
            }

            string query = string.Format("Story?sel={1}&Where=IsDeleted='False';AssetState='Active';Scope.Name='{0}'", Encoder.UrlEncode(project.Name), Encoder.UrlEncode(string.Join(",", Story.VersionOneAttributeNameDictionary.Values)));

            if (status != null)
            {
                query += string.Format(";Status.Name='{0}'", status);
            }

            var ret = DataConnection.Execute(query);

            var assets = ret.Element("Assets");
            if (assets == null)
            {
                return null;
            }

            var linqQuery = from c in assets.Descendants("Asset")
                            select
                                new Story
                                {
                                    Name = Util.GetValue<string>(Story.VersionOneAttributeNameDictionary["Name"], c),
                                    CreateDate = Util.GetValue<DateTime>(Story.VersionOneAttributeNameDictionary["CreateDate"], c),
                                    ImpedimentCategory = Util.GetValue<string>(Story.VersionOneAttributeNameDictionary["ImpedimentCategory"], c),
                                    Description = Util.StripTags(Util.GetValue<string>(Story.VersionOneAttributeNameDictionary["Description"], c)),
                                    Id = Util.GetValue<string>(Story.VersionOneAttributeNameDictionary["Id"], c),
                                    Status = Util.GetValue<string>(Story.VersionOneAttributeNameDictionary["Status"], c),
                                    Team = Util.GetValue<string>(Story.VersionOneAttributeNameDictionary["Team"], c),
                                    Reference = Util.GetValue<string>(Story.VersionOneAttributeNameDictionary["Reference"], c),
                                    Theme = Util.GetValue<string>(Story.VersionOneAttributeNameDictionary["Theme"], c)
                                };

            return linqQuery.ToList();
        }
    }
}